package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import jndi.JndiFactory;

import model.Book;
import exception.BookNotDeletedException;
import exception.BookNotSavedException;
import exception.BookNotFoundException;

public class BookDaoImpl implements BookDao {
	
	final JndiFactory jndi = JndiFactory.getInstance();

	@Override
	public void delete(Long id) {
		
		if (id == null)
			throw new IllegalArgumentException("id can not be null");
		
		Connection connection = null;		
		try {
			connection = jndi.getConnection("jdbc/libraryDB");		
			PreparedStatement pstmt = connection.prepareStatement("delete from books where id = ?");
			pstmt.setLong(1, id);
			pstmt.executeUpdate();			
		} catch (Exception e) {
			throw new BookNotDeletedException(id);
		} finally {
			closeConnection(connection);
		}
	}

	@Override
	public Book get(Long id) {
		
		if (id == null)
			throw new IllegalArgumentException("id can not be null");
		
		Connection connection = null;		
		try {
			connection = jndi.getConnection("jdbc/libraryDB");			
			PreparedStatement pstmt = connection.prepareStatement("select id, title, author from books where id = ?");
			pstmt.setLong(1, id);
			ResultSet rs = pstmt.executeQuery();							
			if (rs.next()) {
				Book book = new Book();
				book.setId(rs.getLong("id"));
				book.setTitle(rs.getString("title"));
				book.setAuthor(rs.getString("author"));
				return book;
			} else {
				throw new BookNotFoundException(id);
			}			
		} catch (Exception e) {
			throw new BookNotFoundException(id);
		} finally {	
			closeConnection(connection);
		}
	}

	@Override
	public void save(Book book) {
		
		if (book == null)
			throw new IllegalArgumentException("book can not be null");
		
		Connection connection = null;		
		try {
			connection = jndi.getConnection("jdbc/libraryDB");			
			if (book.getId() == null) {
				PreparedStatement pstmt = connection.prepareStatement("insert into books (title, author) values (?,?)");
				pstmt.setString(1, book.getTitle());
				pstmt.setString(2, book.getAuthor());
				pstmt.executeUpdate();
			} else {
				PreparedStatement pstmt = connection.prepareStatement("update books set title = ?, author = ? where id = ?");
				pstmt.setString(1, book.getTitle());
				pstmt.setString(2, book.getAuthor());
				pstmt.setLong(3, book.getId());
				pstmt.executeUpdate();
			}			
		} catch (Exception e) {
			throw new BookNotSavedException();
		} finally {
			closeConnection(connection);
		}
	}	

	@Override
	public List<Book> list() {
		
		List<Book> bookList = new ArrayList<Book>();
		
		Connection connection = null;		
		try {
			connection = jndi.getConnection("jdbc/libraryDB");			
			
				PreparedStatement pstmt = connection.prepareStatement("select id, title, author from books");				
				ResultSet rs = pstmt.executeQuery();
								
				while (rs.next()) {
					Book book = new Book();
					book.setId(rs.getLong("id"));
					book.setTitle(rs.getString("title"));
					book.setAuthor(rs.getString("author"));
					bookList.add(book);
				}			
			
			return bookList;
		} catch (Exception e) {
			throw new BookNotFoundException();
		} finally {	
			closeConnection(connection);
		}
	}
	
	private void closeConnection(Connection connection) {
		if (connection != null) {
			try {
				connection.close();
				connection = null;
			} catch (SQLException e) {
				// nothing to do
				e.printStackTrace();
			}				
		}
	}
}
